//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Validation Application Block
//===============================================================================

using System;
using System.Drawing.Design;
using System.Windows.Forms;
using System.IO;
using System.ComponentModel;
using System.Security.Permissions;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design;
using EntLibContrib.Validation.Configuration.Design.Properties;

namespace EntLibContrib.Validation.Configuration.Design
{
	/// <summary>
	/// Open File Editor
	/// </summary>
	[PermissionSet(SecurityAction.InheritanceDemand, Name = "FullTrust")]
	[PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
	public class OpenFileEditor : UITypeEditor
	{
		#region Fields
		private string file;
		private FilteredFileNameEditorAttribute editorAttribute;
		#endregion

		#region Public Methods
		/// <summary>
		/// Edits the specified object's value using the editor style indicated by the <see cref="M:System.Drawing.Design.UITypeEditor.GetEditStyle"/> method.
		/// </summary>
		/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that can be used to gain additional context information.</param>
		/// <param name="provider">An <see cref="T:System.IServiceProvider"/> that this editor can use to obtain services.</param>
		/// <param name="value">The object to edit.</param>
		/// <returns>
		/// The new value of the object. If the value of the object has not changed, this should return the same object it was passed.
		/// </returns>
		public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
		{
			if (null == context) return value;
			if (null == provider) return value;

			file = value as string;
			foreach (Attribute attribute in context.PropertyDescriptor.Attributes)
			{
				editorAttribute = attribute as FilteredFileNameEditorAttribute;
				if (editorAttribute != null)
				{
					break;
				}
			}

			using (OpenFileDialog openFileDlg = new OpenFileDialog())
			{
				InitializeDialog(openFileDlg);
				if (null != file && -1 == file.IndexOfAny(Path.GetInvalidFileNameChars()))
				{
					openFileDlg.FileName = file;
				}

				if (openFileDlg.ShowDialog() == DialogResult.OK)
				{
					value = openFileDlg.FileName;
				}
			}
			return value;
		}

		/// <summary>
		/// Gets the editor style used by the <see cref="EditValue"/> method.
		/// </summary>
		/// <param name="context">An <see cref="ITypeDescriptorContext"/> that can be used to gain additional context information.</param>
		/// <returns>
		/// 	<see cref="UITypeEditorEditStyle.Modal"/>
		/// </returns>
		public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
		{
			return UITypeEditorEditStyle.Modal;
		}
		#endregion

		#region Protected Methods
		/// <summary>
		/// Initializes the save file dialog when it is created.
		/// </summary>
		/// <param name="fileDialog">A <see cref="FileDialog"/> instance.</param>
		protected virtual void InitializeDialog(FileDialog fileDialog)
		{
			if (editorAttribute == null)
			{
				fileDialog.Filter = Resources.GenericFileFilter;
			}
			else
			{
				fileDialog.Filter = editorAttribute.Filter;
			}
			fileDialog.Title = Resources.GenericOpenFile;
			if (file != null && file.Length > 0 && -1 == file.IndexOfAny(Path.GetInvalidFileNameChars()))
			{
				fileDialog.InitialDirectory = Path.GetDirectoryName(Path.GetFullPath(file));
			}
		}
		#endregion
	}
}
